<template>
  <div class="scroll-list-container" ref="container" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
    <div class="scroll-list-wrapper" :class="{ 'is-scrolling': isScrolling, 'is-paused': isPaused }" :style="wrapperStyle" @transitionend="onTransitionEnd">
      <div v-for="(item, index) in visibleList" :key="index" class="scroll-list-item" :class="{ 'is-active': currentIndex === index }">
        <slot name="item" :item="item" :index="getOriginalIndex(index)">
          <div class="default-item">{{ getItemContent(item) }}</div>
        </slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ScrollList",
  props: {
    // 列表数据
    data: {
      type: Array,
      required: true,
      default: () => []
    },
    //是否开启自动加载更多数据
    isLoadMore: {
      type: Boolean,
      default: true
    },
    // 每页加载的条数
    pageSize: {
      type: Number,
      default: 15,
      validator: value => value > 0
    },
    // 滚动间隔时间(毫秒)
    interval: {
      type: Number,
      default: 3000,
      validator: value => value >= 500
    },
    // 动画持续时间(毫秒)
    duration: {
      type: Number,
      default: 500,
      validator: value => value > 0 && value < 3000
    },
    // 是否自动开始滚动
    autoplay: {
      type: Boolean,
      default: true
    },
    // 同时显示的行数
    rowsToShow: {
      type: Number,
      default: 5,
      validator: value => value > 0
    },
    // 最大显示的行数
    maxRows: {
      type: Number,
      default: 100,
      validator: value => value > 0
    }
  },
  data() {
    return {
      currentIndex: 0,
      itemHeight: 0,
      timer: null,
      isScrolling: false,
      isPaused: false,
      displayList: [],
      offset: 0,
      isInitialized: false,
      shouldScroll: true,
      lastScrollTime: Date.now(),
      needsReset: false,
      isUpdating: false
    };
  },
  computed: {
    wrapperStyle() {
      return {
        transform: `translateY(${-this.offset}px)`,
        transition: this.isScrolling ? `transform ${this.duration}ms cubic-bezier(0.23, 1, 0.32, 1)` : "none"
      };
    },
    visibleList() {
      // 创建循环列表以实现无缝滚动
      if (this.displayList.length === 0) return [];

      let list = [...this.displayList];
      // 在末尾添加开头的部分数据用于无缝衔接
      // list.push(...this.displayList.slice(0, this.rowsToShow))
      return list;
    }
  },
  created() {
    this.initDisplayList();
  },
  mounted() {
    this.$nextTick(this.initialize);
  },
  beforeDestroy() {
    this.cleanup();
  },
  methods: {
    initDisplayList() {
      this.displayList = this.data.slice(0, this.maxRows);
      this.shouldScroll = this.displayList.length > this.rowsToShow;
    },
    getItemContent(item) {
      return typeof item === "object" ? item.value || item.name || "" : item;
    },
    getOriginalIndex(index) {
      return index % this.displayList.length;
    },
    initialize() {
      if (!this.$refs.container) return;
      //获取组件父元素的可视化高度
      this.parentHeight = this.$parent.$el.clientHeight || 200;
      const item = this.$refs.container.querySelector(".scroll-list-item");
      if (!item) return;

      this.itemHeight = item.offsetHeight;
      this.offset = 0;
      this.isInitialized = true;

      if (this.autoplay && this.shouldScroll && !this.isPaused) {
        this.startAutoScroll();
      }
    },
    startAutoScroll() {
      if (this.timer) {
        clearInterval(this.timer);
      }
      this.timer = setInterval(() => {
        this.scrollNext();
      }, this.interval);
    },
    stopAutoScroll() {
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }
    },
    handleMouseEnter() {
      if (this.autoplay) {
        this.isPaused = true;
        this.stopAutoScroll();
      }
    },
    handleMouseLeave() {
      if (this.autoplay && this.shouldScroll) {
        this.isPaused = false;
        this.startAutoScroll();
      }
    },
    scrollNext() {
      if (this.isScrolling || !this.isInitialized || this.isPaused || this.isUpdating) return;

      const now = Date.now();
      if (now - this.lastScrollTime < this.duration) return;

      this.isScrolling = true;
      this.lastScrollTime = now;

      const maxOffset = this.displayList.length * this.itemHeight;
      if (this.offset + this.parentHeight - this.itemHeight * 2 >= maxOffset) {
        // 如果到达末尾，检查是否需要加载更多数据
        if ((this.displayList.length < this.maxRows) && (this.displayList.length >= this.pageSize) && this.isLoadMore) {
          this.$emit("loadMore");
          this.handleMouseEnter();
        } else {
          // 重置到开头位置
          this.offset = 0;
        }
      } else {
        this.offset += this.itemHeight;
      }

      this.$emit("scroll", {
        index: Math.floor(this.offset / this.itemHeight) % this.displayList.length,
        timestamp: now
      });
    },
    onTransitionEnd() {
      this.isScrolling = false;

      if (this.needsReset) {
        this.offset = 0;
        this.needsReset = false;
      }
    },
    cleanup() {
      this.stopAutoScroll();
    },
    // 公开方法
    pause() {
      this.isPaused = true;
      this.stopAutoScroll();
    },
    resume() {
      if (this.shouldScroll) {
        this.isPaused = false;
        this.startAutoScroll();
      }
    },
    reset() {
      this.offset = 0;
      this.currentIndex = 0;
      this.isScrolling = false;
      this.initDisplayList();
    }
  },
  watch: {
    data: {
      handler(newData) {
        this.isUpdating = true;

        // 保存当前滚动位置相关信息
        const currentScrollIndex = Math.floor(this.offset / this.itemHeight);

        // 更新显示列表，但限制最大显示数量
        this.displayList = newData.slice(0, this.maxRows);

        this.$nextTick(() => {
          if (!this.isInitialized) {
            this.initialize();
          } else {
            // 如果之前已经初始化过，需要调整滚动位置
            if (this.offset > 0) {
              // 确保新数据加载后保持在相对合适的位置
              const maxOffset = this.displayList.length * this.itemHeight;
              this.offset = Math.min(currentScrollIndex * this.itemHeight, maxOffset);
            }
          }
          this.shouldScroll = this.displayList.length > this.rowsToShow;

          if (this.shouldScroll) {
            this.onTransitionEnd()
            this.handleMouseLeave();
          }

          this.isUpdating = false;
        });
      },
      deep: true,
      immediate: true
    }
  }
};
</script>

<style scoped>
.scroll-list-container {
  width: 100%;
  overflow: hidden;
  position: relative;
  /* background: #fff; */
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.scroll-list-wrapper {
  will-change: transform;
  backface-visibility: hidden;
}

.scroll-list-wrapper.is-paused {
  transition: none !important;
}

.scroll-list-item {
  box-sizing: border-box;
  padding: 10px;
  transition: background-color 0.3s ease;
}

.scroll-list-item.is-active {
  background-color: rgba(0, 0, 0, 0.02);
}

.scroll-list-item:hover {
  background-color: rgba(0, 0, 0, 0.04);
}

.default-item {
  display: flex;
  align-items: center;
  height: 40px;
  padding: 0 15px;
  font-size: 14px;
  color: #333;
}
</style>
